import java.util.List;
import java.util.ArrayList;

/**
 * An AppleScript controller that uses just 'one' application.
 * The name of the application passed into the constructor will
 * be used in 
 * <code>tell application"</code><em>application</em><code>"</code>.
 */
final class ApplicationController {

  private final Object target;
  private final String application;
  private final AppleScriptExecutor app = new AppleScriptExecutor();
  private boolean debug;

  /**
   * @param target Object using this
   * @param application used in the context of
   *        <code>tell application"</code><em>application</em><code>"</code>.
   */
  ApplicationController(Object target, String application) {
    this.target = target;
    this.application = application;
  }

  /** 
   * Sets debugging to <code>debug</code>
   *
   * @param debug whether to debug or not
   */
  public void setDebug(boolean debug) {
    this.debug = debug;
  }

  /**
   * Executes the <code>lines</code> in the context
   * <pre>
   * tell application "&lt;application&gt;"
   * </pre>
   * line1<br/>
   * line2<br/>
   * ...<br/>
   * linen<br/>
   * <pre>
   * end tell
   * </pre>
   */
  public String execute(String[] lines) {
    StringBuffer s = new StringBuffer();
    s.append("tell application \"" + application + "\"\n");
    for (String line : lines) s.append(line).append("\n");
    s.append("end tell\n");
    if (debug) System.err.println(s);
    return app.execute(s.toString());
  }

  /**
   * Executes a single <code>line</code> by delegating to {@link #execute(String[])}.
   *
   * @param line line to execute
   * @see #execute(String[])
   */
  public String execute(String line) {
    return execute(new String[]{line});
  }

  /**
   * Executes <code>lines</code> by delegating to {@link #execute(String[])}.
   *
   * @param lines lines to execute
   * @see #execute(String[])
   */
  public String execute(List<String> lines) {
    return execute(lines.toArray(new String[0]));
  }

  public void realMain(String[] args) throws java.io.IOException {
    boolean debug = args.length > 0 && args[0].equals("-debug");
    debug = true;
    setDebug(debug);
    System.out.println("Type a script and then '.' or 'quit' to quit...");
    final List<String> script = new ArrayList<String>();
    java.io.BufferedReader in = 
      new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
    while (true) {
      System.out.print("> ");
      System.out.flush();
      String line = in.readLine();
      if (line.equals("quit")) break;
      if (line.equals(".")) {
        System.out.println(execute(script));
        script.clear();
      } else {
        boolean execute = false;
        if (line.endsWith(".")) {
          line = line.substring(0,line.length()-1);
          execute = true;
        }
        script.add(line);
        if (execute) {
          System.out.println(execute(script));
          script.clear();
        }
      }
    }
  }
}